package game.manager;

import game.Constants;
import game.Event;
import game.screen.Screen;
import game.screen.TitleScreen;

import java.util.Observable;
import java.util.Stack;

/**
 * Implements Singleton design pattern
 * 
 * @author churchmf
 * 
 */
public class ScreenManager implements Manager {
	private Stack<Screen> backward;
	private Stack<Screen> forward;
	private Screen active;

	private static ScreenManager manager;

	public static ScreenManager getManager() {
		if (manager == null)
			manager = new ScreenManager();
		return manager;
	}

	private ScreenManager() {
		this.initialize();
	}

	@Override
	public void initialize() {
		this.active = new TitleScreen();
		this.backward = new Stack<Screen>();
		this.forward = new Stack<Screen>();
	}

	@Override
	public void gameUpdate() {
		if (Constants.DEBUG) {
			this.active.print();
		}

		this.active.draw();
	}

	public void activateScreen(Screen screen) {
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		this.activateScreen(screen, true);
	}

	public void activateScreen(Screen screen, boolean canReturn) {
		if (!canReturn)
			this.backward.clear();
		else
			this.backward.push(this.active);
		this.forward.clear();
		this.setActiveScreen(screen);
	}

	private void setActiveScreen(Screen screen) {
		this.active = screen;
		this.active.refreshScreen();
	}

	public boolean canGoBack() {
		return !this.backward.isEmpty();
	}

	public boolean canGoForward() {
		return !this.forward.isEmpty();
	}

	public void goBack() {
		if (!this.backward.isEmpty()) {
			this.forward.push(this.active);
			Screen pop = backward.pop();
			this.setActiveScreen(pop);
		}
	}

	public void goForward() {
		if (!this.forward.isEmpty()) {
			this.backward.push(this.active);
			Screen pop = forward.pop();
			this.setActiveScreen(pop);
		}
	}

	@Override
	public void update(Observable o, Object arg) {
		final Event event = (Event) arg;

		switch (event.getType()) {
		case RESET:
			this.backward.clear();
			this.forward.clear();
			break;
		}
	}

	public Screen getActiveScreen() {
		return this.active;
	}
}
